package master.quantumComputerIO.gate;

import java.lang.reflect.InvocationTargetException;

import gates.*;

public class QuantumGateFactory {
	private final Class gateClass;
	private final String name;
	private final String [] annotations;
	private final Class [] constructorTypes;
	public QuantumGateFactory(Class gateClass, int constructor) throws GateException{
		if(!QuantumGate.class.isAssignableFrom(gateClass))
			throw new GateException("not an instance of quantum gate");
		this.gateClass = gateClass;
		this.name = gateClass.getName();
		this.annotations = QuantumGateIO.getConstructorAnnotation(gateClass, constructor);
		this.constructorTypes = QuantumGateIO.getConstructorTypes(gateClass, constructor);
	}
	public static QuantumGateFactory [] factoriesForClasses(Class [] classes) throws GateException{
		int [] defaults = new int[classes.length];
		for(int i = 0 ; i < defaults.length;i++) defaults[i] = 0;
		return factoriesForClasses(classes,defaults);
	}
	public static QuantumGateFactory [] factoriesForClasses(Class [] classes, int [] constructors) throws GateException{
		if(classes.length!=constructors.length||classes.length<=0)
			throw new IllegalArgumentException("Invalid input");
		QuantumGateFactory [] facts = new QuantumGateFactory[classes.length];
		for(int i = 0 ; i < classes.length ;i++){
			facts[i] = new QuantumGateFactory(classes[i],constructors[i]);
		}
		return facts;
	}
	public String getGateName(){
		return name;
	}
	public String [] getGateArgumentAnnotations(){
		return annotations;
	}
	public Class [] getGateArgumentTypes(){
		return constructorTypes;
	}
	public QuantumGate getGate(Object [] constructorArguments)throws GateException{
		if(constructorArguments.length!=constructorTypes.length)
			throw new GateException("Illegal Gate Constructor");
		for(int i = 0 ; i < constructorArguments.length ;i++)
			if(constructorArguments[i].getClass().equals( constructorTypes[i]))
				throw new GateException("Illegal Gate Constructor Argument "
						+ constructorArguments[i].getClass() + " should be " + constructorTypes[i]);
		try {
			return (QuantumGate) gateClass.getConstructors()[0].newInstance(constructorArguments);
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		throw new GateException("Error, unable to load gate");
	}
}
